using System;
using System.Globalization;
using System.Linq;
using System.Web;
using System.Xml.Linq;
using DotNetNuke.Common;
using DotNetNuke.Common.Utilities;

namespace HeroldIT.Dnn.Modules.News.Views
{
    public class NewsListContainer : ContainerBase, INewsListSettingsProvider, ISyndicatable
    {
        #region static methods

        protected static bool HasDetailView(NewsEntry entry)
        {
            return !String.IsNullOrEmpty(entry.Details[0].DetailUrl)
                   || !String.IsNullOrEmpty(entry.Details[0].DetailText);
        }

        #endregion

        #region properties

        /// <summary>
        /// Gets the default skin url.
        /// </summary>
        protected override string DefaultSkinUrl
        {
            get { return "[M]DefaultViews/List.ascx"; }
        }

        /// <summary>
        /// Gets the specific skin url.
        /// </summary>
        protected override string SkinUrl
        {
            get { return this.GetListSkinUrl(); }
        }

        private UrlController urlController;

        protected UrlController UrlController
        {
            get
            {
                if (null == this.urlController)
                {
                    this.urlController = new UrlController();
                }
                return this.urlController;
            }
        }

        #endregion

        #region methods

        protected UrlTrackingInfo GetUrlTrackingInfo(NewsEntry entry)
        {
            return this.UrlController.GetUrlTracking(this.PortalSettings.PortalId, entry.Details[0].DetailUrl,
                                                     this.ModuleConfiguration.ModuleID);
        }

        protected string GenerateDetailUrl(NewsEntry entry)
        {
            string detailUrl = entry.Details[0].DetailUrl;
            if (!String.IsNullOrEmpty(detailUrl))
            {
                UrlTrackingInfo trackingInfo = this.GetUrlTrackingInfo(entry);
                return Globals.LinkClick(detailUrl, this.ModuleConfiguration.TabID, this.ModuleConfiguration.ModuleID,
                                         null == trackingInfo ? false : trackingInfo.TrackClicks);
            }
            return this.GenerateDetailUrl(entry.NewsEntryId);
        }

        protected string GenerateDetailUrl(int newsEntryId)
        {
            if (this.Controller.HasCoreModule())
            {
                return this.Controller.GenerateDetailUrl(newsEntryId);
            }
            return null;
        }

        #endregion

        #region ISyndicatable

        /// <summary>
        /// Generates a custom rss feed.
        /// </summary>
        /// <returns>The rss feed xml document.</returns>
        public XDocument GenerateRssFeed()
        {
            if (!this.Controller.HasCoreModule())
                return null;

            int skip = 0;
            int maxCurrentItems = this.Controller.GetMaxCurrentItems();
            if (!this.GetShowCurrentItems())
            {
                skip += maxCurrentItems;
            }
            int take = this.GetMaxVisibleItems();
            if (!this.GetShowArchivedItems() && skip + take > maxCurrentItems)
            {
                take = maxCurrentItems - skip;
            }
            var entries = this.Controller.ReadNewsEntries(CultureInfo.CurrentUICulture.Name, skip, take);
            DateTime lastUpdate;
            if (entries == null || entries.Count <= 0)
            {
                lastUpdate = DateTime.Now.ToUniversalTime();
            }
            else
            {
                DateTime date = entries.Max(e => e.DisplayDate);
                lastUpdate = new DateTime(date.Year, date.Month, date.Day, 12, 0, 0, 0, DateTimeKind.Utc);
            }
            XNamespace ns = "http://www.w3.org/2005/Atom";
            return new XDocument(
                new XDeclaration("1.0", "UTF-8", "yes"),
                new XElement(ns + "feed",
                    new XElement(ns + "title", this.PortalSettings.PortalName + " - " + this.ModuleConfiguration.ModuleTitle),
                    new XElement(ns + "link",
                        new XAttribute("href", RssFeed.CompleteUrl(Globals.NavigateURL(this.PortalSettings.ActiveTab.TabID)))
                    ),
                    new XElement(ns + "link",
                        new XAttribute("rel", "self"),
                        new XAttribute("href", HttpContext.Current.Request.Url)
                    ),
                    new XElement(ns + "updated", lastUpdate.ToString("o", CultureInfo.InvariantCulture)),
                    new XElement(ns + "author",
                        new XElement(ns + "name", this.PortalSettings.PortalName)
                    ),
                    new XElement(ns + "id", RssFeed.CompleteUrl(Globals.NavigateURL(this.PortalSettings.ActiveTab.TabID))),
                    new XElement(ns + "generator", "HeroldIT.News DotNetNuke module"),
                    (this.GetCategoryFilter() ?? Enumerable.Empty<string>()).Select(c => new XElement(ns + "category",
                        new XAttribute("term", c)
                    )),
                    (entries ?? Enumerable.Empty<NewsEntry>()).Select(e => new XElement(ns + "entry",
                        new XElement(ns + "id", RssFeed.CompleteUrl(HasDetailView(e) ? this.GenerateDetailUrl(e) : Globals.NavigateURL(this.PortalSettings.ActiveTab.TabID) + "#news" + this.ModuleConfiguration.ModuleID + "-" + e.NewsEntryId)),
                        new XElement(ns + "title", e.Details[0].Headline + (String.IsNullOrEmpty(e.Details[0].Subline) ? String.Empty : " - " + e.Details[0].Subline)),
                        new XElement(ns + "updated", new DateTime(e.DisplayDate.Year, e.DisplayDate.Month, e.DisplayDate.Day, 12, 0, 0, 0, DateTimeKind.Utc).ToString("o", CultureInfo.InvariantCulture)),
                        new XElement(ns + "link",
                            new XAttribute("rel", "alternate"),
                            new XAttribute("href", RssFeed.CompleteUrl(HasDetailView(e) ? this.GenerateDetailUrl(e) : Globals.NavigateURL(this.PortalSettings.ActiveTab.TabID) + "#news" + this.ModuleConfiguration.ModuleID + "-" + e.NewsEntryId))
                        ),
                        new XElement(ns + "summary", HttpUtility.HtmlDecode(HtmlUtils.StripTags(e.Details[0].TeaserText, false)))
                    ))
                )
            );
        }

        #endregion
    }
}
